package com.hawk.eye.server.controller.hawkeye;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.hawk.eye.common.core.ApiResult;
import com.hawk.eye.common.utils.StringUtil;
import com.hawk.eye.common.page.PageQuery;
import com.hawk.eye.common.page.PageResult;
import com.hawk.eye.server.convert.ServiceLogConvert;
import com.hawk.eye.server.delegate.LogMessageStorageDelegate;
import com.hawk.eye.api.storage.dto.ServiceLogRespDTO;
import com.hawk.eye.server.domain.vo.req.ServiceLogReqVO;
import com.hawk.eye.server.domain.vo.resp.ServiceLogRespVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 告警日志 Controller
 * @author: salad
 * @date: 2023/9/30
 **/
@Slf4j
@RestController
@RequestMapping("/hawk-eye/log/")
@RequiredArgsConstructor
public class ServiceLogController {

    private final LogMessageStorageDelegate alarmLogStorageDelegate;

    /**
     * 分页查询告警日志
     * @param pageQuery
     * @param reqVO
     * @return
     */
    @PreAuthorize("@ss.hasPermi('hawk-eye:log:query')")
    @GetMapping("/page")
    public PageResult<ServiceLogRespVO> page(PageQuery pageQuery, ServiceLogReqVO reqVO) {
        PageResult<ServiceLogRespDTO> pageResult = alarmLogStorageDelegate.getAlarmLogStorage()
                .page(pageQuery, ServiceLogConvert.INSTANCE.to(reqVO));
        return PageResult.of(pageResult, ServiceLogConvert.INSTANCE::to);
    }

    /**
     * 告警日志详情
     * @param baseAlarmId
     * @return
     */
    @PreAuthorize("@ss.hasPermi('hawk-eye:log:query')")
    @GetMapping(value = "detail/{baseAlarmId}")
    public ApiResult<ServiceLogRespVO> detail(@PathVariable("baseAlarmId") Long baseAlarmId) {
        ServiceLogRespDTO serviceLogRespDTO = alarmLogStorageDelegate.getAlarmLogStorage().detail(baseAlarmId);
        return ApiResult.ok(ServiceLogConvert.INSTANCE.to(serviceLogRespDTO));
    }

    /**
     * 导出告警日志
     * @param baseAlarmId
     * @param response
     * @throws IOException
     */
    @PreAuthorize("@ss.hasPermi('hawk-eye:log:query')")
    @PostMapping(value = "export-log-txt")
    public void exportLogTxt(@RequestParam Long baseAlarmId, HttpServletResponse response) throws IOException {
        ServiceLogRespDTO serviceLogRespDTO = alarmLogStorageDelegate.getAlarmLogStorage().detail(baseAlarmId);
        StringBuilder sb = new StringBuilder();
        sb.append("链路ID:").append(serviceLogRespDTO.getTraceId()).append("\n");
        sb.append("服务名:").append(StringUtil.format("{}({})",
                serviceLogRespDTO.getServiceCnName(), serviceLogRespDTO.getServiceZnName())).append("\n");
        sb.append("告警时间:").append(serviceLogRespDTO.getAlarmTime()).append("\n");
        sb.append("负责人:").append(serviceLogRespDTO.getChargeUserName()).append("\n");
        sb.append("告警标识:").append(serviceLogRespDTO.getStackHash()).append("\n");
        sb.append("请求地址:").append(serviceLogRespDTO.getRequestUri()).append("\n");
        sb.append("代码文件:").append(serviceLogRespDTO.getErrorFileName()).append("\n");
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        sb.append("详细信息:").append("\n").append(objectMapper.writeValueAsString(serviceLogRespDTO.getLogMessage()));
        response.setCharacterEncoding("utf-8");
        //设置响应的内容类型
        response.setContentType("text/plain");
        //设置文件的名称和格式
        response.addHeader("Content-Disposition", "attachment;filename=log.txt");
        try (ServletOutputStream outStr = response.getOutputStream();
             BufferedOutputStream buff = new BufferedOutputStream(outStr)) {
            buff.write(sb.toString().getBytes(StandardCharsets.UTF_8));
            buff.flush();
        }
    }

}
